package boerseTest.mainTest.AssetsTest;

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

import boerse.main.Asset.CashAccount;
import boerse.main.Asset.Share;
import boerse.main.Asset.ShareDeposit;
import boerse.main.Asset.ShareItem;
import boerse.main.Exceptions.*;
import boerse.main.StockPriceProvider.RandomStockPriceProvider;

public class ShareDepositTest {

	ShareDeposit shareDeposit;
	RandomStockPriceProvider provider;
	CashAccount acc;
	Share bmw;
	Share kuka;
	
	@Before
	public void setUp() {
		shareDeposit = new ShareDeposit("TestDeposit");
		provider = new RandomStockPriceProvider();
		Share[] addShare = {new Share("bmw", 250), new Share("kuka", 204)};
	    provider.addShare(addShare);
		acc = new CashAccount("TestAccount");
		bmw = provider.getShare("bmw");
		kuka = provider.getShare("kuka");
		
	}
	
	@Test
	public void testBuy() throws NegativeValueException, NotEnoughMoneyException {
			
		acc.addMoney(100000000000l);
		shareDeposit.buy(bmw, 1, acc);
		shareDeposit.buy(bmw, 10, acc);
				
		ShareItem[] shareItems = shareDeposit.getAllSharesAsSnapshot();
		int count = 0;
		
		while (count < shareItems.length) {
			if (shareItems[count].getName().equals("bmw"))
				break;
			count++;
		}
		
		assertEquals("Try to buy one bmw share", 11, shareDeposit.getAllSharesAsSnapshot()[count].getQuantity());
	}
	
	@Test(expected = NotEnoughMoneyException.class)
	public void testBuyNotEnoughMoneyException() throws NotEnoughMoneyException, NegativeValueException {
		shareDeposit.buy(bmw, 1, acc);
	}
	
	
	@Test(expected = NegativeValueException.class)
	public void testBuyNegativeValueException() throws NegativeValueException, NotEnoughMoneyException {
		acc.addMoney(10000000l);
		shareDeposit.buy(bmw, -1, acc);
	}
	
	
	@Test
	public void testSell() throws NegativeValueException, NotEnoughMoneyException, NegativeShareCountException {	
		acc.addMoney(100000000000l);
		shareDeposit.buy(bmw, 10, acc);
		shareDeposit.sell(bmw, 2, acc);
			
		ShareItem[] shareItems = shareDeposit.getAllSharesAsSnapshot();
		int count = 0;
		
		while (count < shareItems.length) {
			if (shareItems[count].getName().equals("bmw"))
				break;
			count++;
		}
		
		assertEquals("Try to sell bmw share", 8, shareDeposit.getAllSharesAsSnapshot()[count].getQuantity());	
		}
	
	
	@Test(expected = NegativeShareCountException.class)
	public void testSellNegativeShareCountException () throws NegativeShareCountException, NegativeValueException, NotEnoughMoneyException{
		acc.addMoney(100000000000l);
		shareDeposit.buy(bmw, 10, acc);
		shareDeposit.sell(bmw, 12, acc);
	}
	
	
	@Test(expected = NegativeValueException.class)
	public void testSellNegativeValueException() throws NegativeValueException, NegativeShareCountException, NotEnoughMoneyException {
		acc.addMoney(100000000000l);
		shareDeposit.buy(bmw, 10, acc);
		shareDeposit.sell(bmw, -12, acc);
	}
	
	
	@Test
	public void testDeterminePrice() throws NotEnoughMoneyException, NegativeValueException {
		long quantityBmw = 5;
		long quantityKuka = 1;
		
		long asset = bmw.getPrice() * quantityBmw + kuka.getPrice() * quantityKuka;

		acc.addMoney(10000000000l);
		shareDeposit.buy(bmw, quantityBmw, acc);
		shareDeposit.buy(kuka, quantityKuka, acc);
			
		assertEquals("DeterminePrice should be same as asset", asset, shareDeposit.determinePrice());

	}
	
	@Test
	public void testGetBuyprice() throws InterruptedException, NotEnoughMoneyException, NegativeValueException {
		acc.addMoney(1000000000l);
		shareDeposit.buy(bmw, 1, acc);
			
		long buyPrice = bmw.getPrice();
			
		provider.updateShareRates(); //wieder runterfahren?
			
		Thread.sleep(2500);

		assertEquals("check buy Price", buyPrice, shareDeposit.getBuyPrice(bmw));
			

	}
	
	@Test
	public void testGetQuantity() throws NotEnoughMoneyException, NegativeValueException {
		long quantityBmw = 5;
		
		acc.addMoney(100000l);
		shareDeposit.buy(bmw, quantityBmw, acc);
			
		assertEquals("The Account should have 5 bmw shares", quantityBmw, shareDeposit.getQuantity(bmw));

		
	}
	
}
